Skip to content

CSHARP-5712: withTransaction API retries too frequently#1841

Merged
sanych-sun merged 15 commits intomongodb:mainfrom
sanych-sun:csharp5712
Jan 20, 2026
Merged

CSHARP-5712: withTransaction API retries too frequently#1841
sanych-sun merged 15 commits intomongodb:mainfrom
sanych-sun:csharp5712

Conversation

@sanych-sun
Copy link
Copy Markdown
Member

@sanych-sun sanych-sun commented Dec 19, 2025

No description provided.

Copilot AI review requested due to automatic review settings December 19, 2025 01:01
@sanych-sun sanych-sun requested a review from a team as a code owner December 19, 2025 01:01
@sanych-sun sanych-sun requested review from adelinowona and papafe and removed request for adelinowona December 19, 2025 01:01
@sanych-sun sanych-sun added the chore Non–user-facing code changes (tests, build scripts, etc.). label Dec 19, 2025
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements the RetryabilityHelper.GetRetryDelayMs method to control retry delays with exponential backoff, addressing the issue of transactions retrying too frequently. The implementation adds jitter to prevent thundering herd problems and includes comprehensive parameter validation.

Key Changes

  • Adds GetRetryDelayMs method with exponential backoff calculation and random jitter
  • Removes unused MongoDB.Driver.Core.Connections import from test file
  • Adds comprehensive test coverage for valid inputs, edge cases, and parameter validation

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/MongoDB.Driver/Core/Operations/RetryabilityHelper.cs Implements the core retry delay calculation with exponential backoff and jitter
tests/MongoDB.Driver.Tests/Core/Operations/RetryabilityHelperTests.cs Adds unit tests for the new method and removes unused import

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/MongoDB.Driver/Core/Operations/RetryabilityHelper.cs Outdated
Ensure.IsGreaterThan(backoffMax, backoffInitial, nameof(backoffMax));

var j = __backoffRandom.NextDouble();
return (int)(j * Math.Min(backoffMax, backoffInitial * Math.Pow(backoffBase, attempt - 1)));
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The calculation backoffInitial * Math.Pow(backoffBase, attempt - 1) may overflow for large attempt values, which would then be capped by Math.Min. Consider adding overflow protection or documenting the maximum safe attempt value to prevent unexpected behavior.

Suggested change
return (int)(j * Math.Min(backoffMax, backoffInitial * Math.Pow(backoffBase, attempt - 1)));
// compute the largest exponent such that backoffInitial * backoffBase^exponent <= backoffMax
var maxExponent = Math.Log(backoffMax / (double)backoffInitial, backoffBase);
var effectiveExponent = attempt - 1;
double delayWithoutJitter;
if (effectiveExponent >= maxExponent)
{
delayWithoutJitter = backoffMax;
}
else
{
delayWithoutJitter = backoffInitial * Math.Pow(backoffBase, effectiveExponent);
}
return (int)(j * delayWithoutJitter);

Copilot uses AI. Check for mistakes.
@sanych-sun sanych-sun requested a review from Copilot December 19, 2025 01:11
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/MongoDB.Driver/Core/Operations/RetryabilityHelper.cs Outdated
@sanych-sun sanych-sun added feature Adds new user-facing functionality. and removed chore Non–user-facing code changes (tests, build scripts, etc.). labels Dec 19, 2025
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/MongoDB.Driver/TransactionExecutor.cs Outdated
Copy link
Copy Markdown
Contributor

@papafe papafe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

}

var subject = CreateSubject(coreSession: mockCoreSession.Object, clock: mockClock.Object);
SetupTransactionState(subject, true);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this related to the ticket?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, changes were rolled back. Thank you for noticing this.

Copy link
Copy Markdown
Contributor

@BorisDog BorisDog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partial review

Comment thread src/MongoDB.Driver/Core/Misc/IRandomNumberGenerator.cs Outdated
Comment thread src/MongoDB.Driver/Core/Misc/IRandomNumberGenerator.cs Outdated
Comment thread src/MongoDB.Driver/TransactionExecutor.cs Outdated
Comment thread src/MongoDB.Driver/TransactionExecutor.cs
@sanych-sun sanych-sun requested a review from BorisDog January 5, 2026 23:32
Comment thread src/MongoDB.Driver/Core/Misc/IRandomNumberGenerator.cs Outdated
Comment thread src/MongoDB.Driver/Core/Misc/ThreadStaticRandom.cs Outdated
Comment thread src/MongoDB.Driver/TransactionExecutor.cs
Comment thread src/MongoDB.Driver/Core/Misc/RandomNumberGenerator.cs Outdated
@sanych-sun sanych-sun requested a review from BorisDog January 6, 2026 04:18
Comment thread tests/MongoDB.Driver.Tests/Core/Misc/DefaultRandomTests.cs
var backoffTime = await ExecuteWithTransactionAsync(1);

var difference = backoffTime - noBackoffTime - TimeSpan.FromSeconds(2.2);
difference.Should().BeLessThan(TimeSpan.FromMilliseconds(1));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we using a 1 millisecond window here instead of a 1 second because we're "faking" the prose test?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. We do not interact with the server, so timing should be more strict. 1ms could be small though, we might will need to adjust it in future.

Comment thread src/MongoDB.Driver/Core/Misc/DefaultRandom.cs Outdated
Comment thread src/MongoDB.Driver/Core/Misc/DefaultRandom.cs
Comment thread tests/MongoDB.Driver.Tests/Core/Misc/DefaultRandomTests.cs
Comment thread src/MongoDB.Driver/TransactionExecutor.cs Outdated
Comment thread src/MongoDB.Driver/TransactionExecutor.cs Outdated
Comment thread src/MongoDB.Driver/TransactionExecutor.cs Outdated
var noBackoffTime = await ExecuteWithTransactionAsync(0);
var backoffTime = await ExecuteWithTransactionAsync(1);

var difference = backoffTime - noBackoffTime - TimeSpan.FromSeconds(2.2);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will
backoffTimeMS.Should().BeApproximately(noBackoffTimeMS + 2200, 1);
be more readable?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread tests/MongoDB.Driver.Tests/Core/Operations/RetryabilityHelperTests.cs Outdated
Comment thread tests/MongoDB.Driver.Tests/Core/Operations/RetryabilityHelperTests.cs Outdated
@sanych-sun sanych-sun requested a review from BorisDog January 8, 2026 20:24
Copy link
Copy Markdown
Contributor

@BorisDog BorisDog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor suggestion

{
return callbackOutcome.Result; // assume callback intentionally ended the transaction
}
if (IsTransactionInStartingOrInProgressState(clientSession))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to ShouldRetryTransaction consider ShouldAbortTransaction(out AbortTransactionOptions)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@sanych-sun sanych-sun requested a review from BorisDog January 15, 2026 19:07
Copy link
Copy Markdown
Contributor

@BorisDog BorisDog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM + minor comment

{
return callbackOutcome.Result; // assume callback intentionally ended the transaction
}
if(ShouldAbortTransaction(operationContext, clientSession, out var abortOptions))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: space after if in both places.

@sanych-sun sanych-sun merged commit 22ed045 into mongodb:main Jan 20, 2026
33 of 36 checks passed
@sanych-sun sanych-sun deleted the csharp5712 branch January 20, 2026 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Adds new user-facing functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants